import { RequestEnum } from '/@/enums/httpEnum';
import { deepMerge } from '/@/utils';
import type { PagResult, ArrResult } from '/#/axios';
import { defHttp } from '/@/utils/http/axios';

/**
 *
 * @description 基本返回结果类型
 * @export
 * @interface BasicResult
 */
export interface BasicResult {
  id: string;
  deleted: Nullable<boolean>;
  created_at: string;
  updated_at: string;
}

/**
 *
 * @description 基本查询参数
 * @export
 * @interface BasicQueryParams
 */
export interface BasicQueryParams {
  query: string;
  ordering: string;
  page: number;
  page_size: number;
}

/**
 *
 * @description
 * @export
 * @abstract 只读API
 * @class BasicReadonlyApi
 * @template T 查询参数
 * @template P 单个Retrieve结果
 */
export class BasicReadonlyApi<T, P> {
  /**
   *
   * @protected
   * @type {string}
   * @memberof BasicReadonlyApi
   */
  protected url: string;
  /**
   *
   * @param url
   */
  constructor(url: string) {
    this.url = url;
  }

  public getUrl(...params: Array<string>) {
    const param = params.join('/');
    return param ? `${this.url}/${param}` : this.url;
  }

  /**
   *
   * 查询并获取对象列表
   * @return {*}  {Promise<R>}
   * @memberof BasicReadonlyApi
   */
  public list(params: Partial<T>): Promise<PagResult<Partial<P>>> {
    return defHttp.request<PagResult<Partial<P>>>({
      url: this.getUrl(),
      method: RequestEnum.GET,
      params: params,
    });
  }

  /**
   *
   * 查询并获取对象列表
   * @return {*}  {Promise<R>}
   * @memberof BasicReadonlyApi
   */
  public listAll(params: Partial<T>): Promise<ArrResult<Partial<P>>> {
    return defHttp.request<ArrResult<Partial<P>>>({
      url: this.getUrl(),
      method: RequestEnum.GET,
      params: deepMerge(params, { list: 'all' }),
    });
  }

  /**
   *
   * 根据ID获取单个对象
   * @param {string} id
   * @return {*}  {Promise<P>}
   * @memberof BasicReadonlyApi
   */
  public retrieve(id: string): Promise<Partial<P>> {
    return defHttp.request<Partial<P>>({
      url: this.getUrl(id),
      method: RequestEnum.GET,
    });
  }

  /**
   *
   * 根据ID获取单个对象
   * @param {string} id
   * @param {string} action
   * @param {params} params
   * @return {*}  {Promise<P>}
   * @memberof BasicReadonlyApi
   */
  public operation(id: string, action: string, params?: object): Promise<Partial<P>> {
    return defHttp.request<Partial<P>>({
      url: this.getUrl(id, action),
      method: RequestEnum.POST,
      params: params,
    });
  }
}

/**
 *
 *
 * @export
 * @abstract 常用create、list、retrieve、delete、update api
 * @class BasicApi
 * @template T 查询参数
 * @template P 单个Retrieve结果或提交写入的数据
 */
export class BasicApi<T, P> extends BasicReadonlyApi<T, P> {
  /**
   *
   * post方法提交创建对象
   * @param {Partial<P>} params
   * @return {*}  {(Promise<P | P[]>)}
   * @memberof BasicApi
   */
  public create(params: Recordable): Promise<Partial<P> | ArrResult<Partial<P>>> {
    return defHttp.request<Partial<P> | ArrResult<Partial<P>>>({
      url: this.getUrl(),
      method: RequestEnum.POST,
      params: params,
    });
  }

  /**
   *
   * delete方法删除对象
   * @param {string} id
   * @return {*}  {*}
   * @memberof BasicApi
   */
  public delete(id: string): Promise<any> {
    return defHttp.request<any>({
      url: this.getUrl(id),
      method: RequestEnum.DELETE,
    });
  }

  /**
   *
   * patch方法更新对象
   * @param {string} id
   * @param {Partial<P>} params
   * @return {*}  {Promise<P>}
   * @memberof BasicApi
   */
  public update(id: string, params: Recordable): Promise<Partial<P>> {
    return defHttp.request<Partial<P>>({
      url: this.getUrl(id),
      method: RequestEnum.PATCH,
      params: params,
    });
  }
}
